package org.opens.web.db.service.impl;

import cn.hutool.core.lang.Assert;
import lombok.extern.slf4j.Slf4j;
import org.opens.db.column.entity.TableEntity;
import org.opens.db.column.service.I_DbInfoService;
import org.opens.db.column.service.DbInfoServiceFactory;
import org.opens.db.constant.DbType;
import org.opens.exception.BusinessException;
import org.opens.util.DatabaseConnectInfoEntity;
import org.opens.db.DynamicDataSourceUtil;
import org.opens.web.db.entity.dto.JdbcConnectionDTO;
import org.opens.web.db.service.DbService;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

@Service
@Slf4j
public class DbServiceImpl implements DbService {

    @Override
    public boolean validJdbcConnection(JdbcConnectionDTO jdbcConnectionDTO) {
        Assert.notNull(jdbcConnectionDTO, "数据库参数不能为空");
        Assert.notNull(jdbcConnectionDTO.getUrl(), "数据库连接不能为空");
        Assert.notNull(jdbcConnectionDTO.getUsername(), "数据库用户名不能为空");
        Assert.notNull(jdbcConnectionDTO.getPassword(), "数据库密码不能为空");

        try (
                Connection connection = DynamicDataSourceUtil.getConnection(jdbcConnectionDTO.getUrl(), jdbcConnectionDTO.getUsername(), jdbcConnectionDTO.getPassword());
                PreparedStatement preparedStatement = connection.prepareStatement("select 1 from dual;");
                ResultSet resultSet = preparedStatement.executeQuery();
        ) {
            // 有值表示连接数据库成功
            while (resultSet.next()) {
                log.info("测试数据库连接成功!");
                return true;
            }
        } catch (SQLException e) {

            throw new BusinessException(e);
        }

        return false;
    }

    @Override
    public List<TableEntity> getTableInfo(JdbcConnectionDTO jdbcConnectionDTO) {
        Assert.notNull(jdbcConnectionDTO, "数据库参数不能为空");
        Assert.notNull(jdbcConnectionDTO.getUrl(), "数据库连接不能为空");
        Assert.notNull(jdbcConnectionDTO.getUsername(), "数据库用户名不能为空");
        Assert.notNull(jdbcConnectionDTO.getPassword(), "数据库密码不能为空");

        DbType dbType = DynamicDataSourceUtil.extractDatabaseTypeFromURL(jdbcConnectionDTO.getUrl());
        if (dbType == null) {
            throw new BusinessException("未提取到有效的数据库类型!");
        }

        String databaseName = DynamicDataSourceUtil.extractDatabaseNameFromURL(jdbcConnectionDTO.getUrl());
        Assert.notBlank(databaseName, "数据库名不能为空!");

        I_DbInfoService serviceInstance = DbInfoServiceFactory.getColumnServiceInstance(dbType);
        if (serviceInstance == null) {
            throw new BusinessException("未找到有效的实现类!");
        }

        DatabaseConnectInfoEntity standDbConnectInfo = DatabaseConnectInfoEntity.builder()
                .dbType(dbType)
                .url(jdbcConnectionDTO.getUrl())
                .username(jdbcConnectionDTO.getUsername())
                .password(jdbcConnectionDTO.getPassword())
                .databaseName(databaseName)
                .build();

        return serviceInstance.getAllTables(standDbConnectInfo);
    }
}
